package com.atguigu.gmall.payment.controller;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.model.enums.PaymentType;
import com.atguigu.gmall.model.payment.PaymentInfo;
import com.atguigu.gmall.payment.config.AlipayConfig;
import com.atguigu.gmall.payment.service.AlipayService;
import com.atguigu.gmall.payment.service.PaymentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author mgx
 * @create 2024-09-04 17:30
 * @Description
 */
@Controller
@RequestMapping("/api/payment/alipay")
public class PaymentApiController {

    @Autowired
    private AlipayService alipayService;

    @Autowired
    private PaymentService paymentService;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 查询支付记录信息
     *
     * @param outTradeNo
     * @return
     */
    @GetMapping("getPaymentInfo/{outTradeNo}")
    @ResponseBody
    public PaymentInfo getPaymentInfo(@PathVariable String outTradeNo) {
        PaymentInfo paymentInfo = paymentService.getPaymentInfo(outTradeNo, PaymentType.ALIPAY.name());
        if (null != paymentInfo) {
            return paymentInfo;
        }
        return null;
    }


    /**
     * http://localhost:8205/api/payment/alipay/closePay/25
     * 关闭支付宝交易记录
     *
     * @param orderId 订单id
     * @return 是否关闭成功
     */
    @GetMapping("/closePay/{orderId}")
    @ResponseBody
    public Boolean closePay(@PathVariable("orderId") Long orderId) {
        Boolean flag = alipayService.closePay(orderId);
        return flag;
    }


    /**
     * http://localhost:8205/api/payment/alipay/checkPayment/30
     * 查询支付宝交易记录
     *
     * @param orderId 订单id
     * @return 是否存在
     */
    @GetMapping("/checkPayment/{orderId}")
    @ResponseBody
    public Boolean checkPayment(@PathVariable("orderId") Long orderId) {
        Boolean flag = alipayService.checkPayment(orderId);
        return flag;
    }

    // /api/payment/alipay/submit/{orderId}
    @RequestMapping("/submit/{orderId}")
    @ResponseBody
    public String alipay(@PathVariable("orderId") Long orderId) {
        String form = alipayService.createaliPay(orderId);
        return form;
    }


    /**
     * 支付宝回调
     * /api/payment/alipay/callback/return
     *
     * @return
     */
    @RequestMapping("callback/return")
    public String callBack() {
        // 同步回调给用户展示信息
        return "redirect:" + AlipayConfig.return_order_url;
    }


    @PostMapping("/callback/notify")
    public String callbackNotify(@RequestParam Map<String, String> paramsMap) {
        // Map<String, String> paramsMap = ... //将异步通知中收到的所有参数都存放到map中
        boolean signVerified = false; // 调用SDK验证签名
        try {
            signVerified = AlipaySignature.rsaCheckV1(paramsMap, AlipayConfig.alipay_public_key,
                    AlipayConfig.charset, AlipayConfig.sign_type);
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
        //  获取异步通知的参数中的订单号！
        String outTradeNo = paramsMap.get("out_trade_no");
        //  获取异步通知的参数中的订单总金额！
        String totalAmount = paramsMap.get("total_amount");
        //  获取异步通知的参数中的appId！
        String appId = paramsMap.get("app_id");
        //  获取异步通知的参数中的交易状态！
        String tradeStatus = paramsMap.get("trade_status");
        // 获取异步通知中的notify_id
        String notifyId = paramsMap.get("notify_id");
        //  根据outTradeNo 查询数据！
        PaymentInfo paymentInfo = paymentService.getPaymentInfo(outTradeNo, PaymentType.ALIPAY.name());
        if (signVerified) {
            // 验签成功后，按照支付结果异步通知中的描述
            //  对支付结果中的业务内容进行二次校验
            //  校验成功后在response中返回success并继续商户自身业务处理，校验失败返回failure
            if (paymentInfo != null && new BigDecimal("0.01").compareTo(new BigDecimal(totalAmount)) == 0 &&
                    AlipayConfig.app_id.equals(appId)) {
                // 校验支付状态: 只有交易通知状态为 TRADE_SUCCESS 或 TRADE_FINISHED 时，支付宝才会认定为买家付款成功。
                if ("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)) {
                    // 回调幂等性 - 此处的过期时间对应支付宝8次回调后的结果
                    Boolean flag = redisTemplate.opsForValue().setIfAbsent(notifyId, notifyId, 1462, TimeUnit.MINUTES);
                    if (flag) {
                        // 消费消息
                        paymentService.paySuccess(outTradeNo, PaymentType.ALIPAY.name(), paramsMap);
                        return "success";
                    } else {
                        return "success";
                    }
                }
            }
        } else {
            // 验签失败则记录异常日志，并在response中返回failure.
            return "failure";
        }
        return "failure";
    }

    // 发起退款！http://localhost:8205/api/payment/alipay/refund/20
    @RequestMapping("/refund/{orderId}")
    @ResponseBody
    public Result refund(@PathVariable Long orderId) {
        // 调用退款接口
        boolean result = alipayService.refund(orderId);
        return Result.ok(result);
    }
}
